const httpStatus = require('http-status');
const DietRecord = require('../models/dietRecord.model');
const ApiError = require('../utils/ApiError');
const mongoose = require('mongoose');
const logger = require('../config/logger'); // 添加日志记录器

/**
 * 创建饮食记录
 * @param {Object} recordBody
 * @returns {Promise<DietRecord>}
 */
const createDietRecord = async (recordBody) => {
  logger.info('【饮食记录创建】开始创建饮食记录');
  logger.debug('【饮食记录创建】记录内容:', JSON.stringify({
    userId: recordBody.userId,
    mealType: recordBody.mealType,
    date: recordBody.date,
    time: recordBody.time,
    foodsCount: recordBody.foods?.length || 0
  }));
  
  try {
    const dietRecord = await DietRecord.create(recordBody);
    logger.info(`【饮食记录创建】创建成功，ID: ${dietRecord._id}`);
    return dietRecord;
  } catch (error) {
    logger.error('【饮食记录创建】创建失败:', error);
    throw error;
  }
};

/**
 * 查询饮食记录列表
 * @param {Object} filter - Mongo filter
 * @param {Object} options - Query options
 * @param {string} [options.sortBy] - Sort option in the format: field:(desc|asc)
 * @param {number} [options.limit] - Maximum number of results per page (default = 10)
 * @param {number} [options.page] - Current page (default = 1)
 * @param {string} [options.search] - Search keyword for food name or notes
 * @returns {Promise<QueryResult>}
 */
const queryDietRecords = async (filter, options) => {
  logger.info('【饮食记录查询】开始查询，传入参数：', { 
    filter: JSON.stringify(filter), 
    options: JSON.stringify(options)
  });

  const { sortBy, limit = 10, page = 1, search } = options;

  const query = { ...filter };
  
  query.isDeleted = { $ne: true };
  logger.debug('【饮食记录查询】构建的查询条件：', JSON.stringify(query));

  if (search) {
    const searchRegex = new RegExp(search, 'i');
    query.$or = [
      { 'foods.food.name': searchRegex },
      { note: searchRegex },
      // 如果需要搜索用户名，可以先populate userId，然后对用户名进行搜索
      // 这需要在此处修改或在控制器中预先处理 userId 筛选
    ];
    logger.debug('【饮食记录查询】添加搜索条件：', JSON.stringify(query.$or));
  }

  const sortOrder = {};
  if (sortBy) {
    const parts = sortBy.split(',');
    parts.forEach((sortOption) => {
      const [key, order] = sortOption.split(':');
      sortOrder[key] = order === 'desc' ? -1 : 1;
    });
  } else {
    sortOrder.date = -1; // 默认按日期倒序
    sortOrder.time = -1; // 其次按时间倒序
  }
  logger.debug('【饮食记录查询】排序规则：', JSON.stringify(sortOrder));

  const skip = (page - 1) * limit;
  logger.debug(`【饮食记录查询】分页参数 - 页码: ${page}, 每页数量: ${limit}, 跳过记录数: ${skip}`);

  try {
    logger.debug('【饮食记录查询】查询数据库中...');
    // 先执行一个简单查询，检查是否有任何记录
    const sampleRecord = await DietRecord.findOne({}).lean();
    logger.debug('【饮食记录查询】数据库中是否有记录：', !!sampleRecord);
    if (sampleRecord) {
      logger.debug('【饮食记录查询】示例记录的结构：', JSON.stringify({
        id: sampleRecord._id,
        fields: Object.keys(sampleRecord)
      }));
    }

    const countPromise = DietRecord.countDocuments(query);
    const docsPromise = DietRecord.find(query)
      .populate('userId', 'name avatar') // 填充用户信息
      .populate('foods.food._id', 'name image unit calories') // 填充食物基础信息（如果需要）
      .sort(sortOrder)
      .skip(skip)
      .limit(limit)
      .lean(); // 使用 lean() 以获得普通JS对象，提高性能

    const [totalResults, results] = await Promise.all([countPromise, docsPromise]);
    logger.info(`【饮食记录查询】查询完成，总记录数: ${totalResults}, 返回记录数: ${results.length}`);
    
    if (results.length > 0) {
      logger.debug('【饮食记录查询】第一条记录部分内容:', JSON.stringify({
        id: results[0]._id,
        userId: results[0].userId,
        mealType: results[0].mealType,
        date: results[0].date,
        foodsCount: results[0].foods?.length || 0
      }));
    } else {
      logger.warn('【饮食记录查询】未找到符合条件的记录');
    }

    const totalPages = Math.ceil(totalResults / limit);
    logger.debug(`【饮食记录查询】总页数: ${totalPages}`);

    return {
      results,
      page,
      limit,
      totalPages,
      totalResults,
    };
  } catch (error) {
    logger.error('【饮食记录查询】查询出错：', error);
    throw error;
  }
};

/**
 * 根据ID获取饮食记录
 * @param {ObjectId} id
 * @returns {Promise<DietRecord>}
 */
const getDietRecordById = async (id) => {
  logger.info(`【饮食记录查询】开始根据ID查询记录: ${id}`);
  try {
    const record = await DietRecord.findOne({ 
      _id: id, 
      isDeleted: { $ne: true }
    })
      .populate('userId', 'name avatar')
      .populate('foods.food._id');
    
    if (record) {
      logger.info(`【饮食记录查询】找到ID为 ${id} 的记录`);
      logger.debug('【饮食记录查询】记录内容:', JSON.stringify({
        id: record._id,
        userId: record.userId,
        mealType: record.mealType,
        date: record.date,
        foodsCount: record.foods?.length || 0
      }));
    } else {
      logger.warn(`【饮食记录查询】未找到ID为 ${id} 的记录`);
    }
    
    return record;
  } catch (error) {
    logger.error(`【饮食记录查询】查询ID为 ${id} 的记录出错:`, error);
    throw error;
  }
};

/**
 * 更新饮食记录
 * @param {ObjectId} dietRecordId
 * @param {Object} updateBody
 * @returns {Promise<DietRecord>}
 */
const updateDietRecordById = async (dietRecordId, updateBody) => {
  logger.info(`【饮食记录更新】开始更新ID为 ${dietRecordId} 的记录`);
  logger.debug('【饮食记录更新】更新内容:', JSON.stringify(updateBody, (key, value) => {
    // 避免日志过大，如果foods数组存在，只记录长度
    if (key === 'foods' && Array.isArray(value)) {
      return `数组(长度: ${value.length})`;
    }
    return value;
  }));
  
  try {
    const dietRecord = await getDietRecordById(dietRecordId);
    if (!dietRecord) {
      logger.warn(`【饮食记录更新】未找到ID为 ${dietRecordId} 的记录`);
      throw new ApiError(httpStatus.NOT_FOUND, '饮食记录未找到');
    }
    
    Object.assign(dietRecord, updateBody);
    await dietRecord.save();
    logger.info(`【饮食记录更新】更新成功，ID: ${dietRecord._id}`);
    return dietRecord;
  } catch (error) {
    logger.error(`【饮食记录更新】更新ID为 ${dietRecordId} 的记录失败:`, error);
    throw error;
  }
};

/**
 * 逻辑删除饮食记录
 * @param {ObjectId} dietRecordId
 * @returns {Promise<DietRecord>}
 */
const deleteDietRecordById = async (dietRecordId) => {
  logger.info(`【饮食记录删除】开始删除ID为 ${dietRecordId} 的记录`);
  
  try {
    const dietRecord = await getDietRecordById(dietRecordId);
    if (!dietRecord) {
      logger.warn(`【饮食记录删除】未找到ID为 ${dietRecordId} 的记录`);
      throw new ApiError(httpStatus.NOT_FOUND, '饮食记录未找到');
    }
    
    dietRecord.isDeleted = true;
    await dietRecord.save();
    logger.info(`【饮食记录删除】删除成功，ID: ${dietRecord._id}`);
    return dietRecord;
  } catch (error) {
    logger.error(`【饮食记录删除】删除ID为 ${dietRecordId} 的记录失败:`, error);
    throw error;
  }
};

/**
 * 获取饮食记录统计摘要
 * @param {Object} queryOptions - 例如 { userId, date, period: 'day'/'week'/'month' }
 * @returns {Promise<Object>}
 */
const getDietRecordSummary = async (queryOptions) => {
  logger.info('【饮食记录统计】开始统计，参数:', JSON.stringify(queryOptions));
  
  const { userId, period = 'week', date } = queryOptions;
  const matchConditions = { isDeleted: { $ne: true } };

  if (userId) {
    matchConditions.userId = new mongoose.Types.ObjectId(userId);
    logger.debug(`【饮食记录统计】为用户 ${userId} 生成统计数据`);
  } else {
    logger.debug('【饮食记录统计】为所有用户生成统计数据');
  }
  
  // 设置日期范围
  const endDate = date ? new Date(date) : new Date();
  endDate.setHours(23, 59, 59, 999);
  
  let startDate;
  
  // 根据统计周期设置开始日期
  if (period === 'day') {
    startDate = new Date(endDate);
    startDate.setHours(0, 0, 0, 0);
    logger.debug(`【饮食记录统计】日统计范围: ${startDate.toISOString()} 至 ${endDate.toISOString()}`);
  } else if (period === 'week') {
    startDate = new Date(endDate);
    startDate.setDate(endDate.getDate() - 6); // 过去7天（含当天）
    startDate.setHours(0, 0, 0, 0);
    logger.debug(`【饮食记录统计】周统计范围: ${startDate.toISOString()} 至 ${endDate.toISOString()}`);
  } else if (period === 'month') {
    startDate = new Date(endDate);
    startDate.setMonth(endDate.getMonth() - 1);
    startDate.setHours(0, 0, 0, 0);
    logger.debug(`【饮食记录统计】月统计范围: ${startDate.toISOString()} 至 ${endDate.toISOString()}`);
  } else {
    throw new ApiError(httpStatus.BAD_REQUEST, `不支持的统计周期: ${period}`);
  }
  
  // 添加日期范围条件
  matchConditions.date = { $gte: startDate, $lte: endDate };
  
  try {
    // 使用聚合管道进行复杂统计
    const pipeline = [
      { $match: matchConditions },
      {
        $group: {
          _id: null,
          totalRecords: { $sum: 1 },
          totalCalories: { $sum: "$totalCalories" },
          totalProtein: { $sum: "$totalNutrition.protein" },
          totalFat: { $sum: "$totalNutrition.fat" },
          totalCarbohydrate: { $sum: "$totalNutrition.carbohydrate" },
          records: { $push: "$$ROOT" }
        }
      }
    ];
    
    logger.debug('【饮食记录统计】聚合管道:', JSON.stringify(pipeline));
    const result = await DietRecord.aggregate(pipeline);
    
    // 如果没有记录，返回默认的空统计
    if (!result.length) {
      logger.info('【饮食记录统计】指定条件下没有找到饮食记录');
      return {
        userId: userId || null,
        period,
        startDate,
        endDate,
        totalRecords: 0,
        totalCalories: 0,
        averageDailyCalories: 0,
        nutritionTotal: { protein: 0, fat: 0, carbohydrate: 0 },
        nutritionAverage: { protein: 0, fat: 0, carbohydrate: 0 },
        mealTypeSummary: {
          "早餐": { count: 0, totalCalories: 0, averageCalories: 0 },
          "午餐": { count: 0, totalCalories: 0, averageCalories: 0 },
          "晚餐": { count: 0, totalCalories: 0, averageCalories: 0 },
          "加餐": { count: 0, totalCalories: 0, averageCalories: 0 }
        },
        dailySummary: []
      };
    }
    
    // 处理统计结果
    const aggregatedData = result[0];
    const days = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24));
    
    // 按餐类型分类记录
    const mealTypeSummary = {
      "早餐": { count: 0, totalCalories: 0, averageCalories: 0 },
      "午餐": { count: 0, totalCalories: 0, averageCalories: 0 },
      "晚餐": { count: 0, totalCalories: 0, averageCalories: 0 },
      "加餐": { count: 0, totalCalories: 0, averageCalories: 0 }
    };
    
    // 按日期分组记录
    const dailyData = {};
    
    // 遍历所有记录处理每日统计和餐类型统计
    aggregatedData.records.forEach(record => {
      // 处理餐类型统计
      if (!mealTypeSummary[record.mealType]) {
        mealTypeSummary[record.mealType] = { count: 0, totalCalories: 0, averageCalories: 0 };
      }
      mealTypeSummary[record.mealType].count += 1;
      mealTypeSummary[record.mealType].totalCalories += record.totalCalories || 0;
      
      // 处理每日统计
      const dateStr = record.date.toISOString().split('T')[0];
      if (!dailyData[dateStr]) {
        dailyData[dateStr] = {
          date: dateStr,
          totalCalories: 0,
          nutrition: { protein: 0, fat: 0, carbohydrate: 0 }
        };
      }
      dailyData[dateStr].totalCalories += record.totalCalories || 0;
      dailyData[dateStr].nutrition.protein += record.totalNutrition?.protein || 0;
      dailyData[dateStr].nutrition.fat += record.totalNutrition?.fat || 0;
      dailyData[dateStr].nutrition.carbohydrate += record.totalNutrition?.carbohydrate || 0;
    });
    
    // 计算各餐类型的平均热量
    Object.keys(mealTypeSummary).forEach(type => {
      const summary = mealTypeSummary[type];
      summary.averageCalories = summary.count > 0 
        ? Math.round(summary.totalCalories / summary.count) 
        : 0;
    });
    
    // 转换每日数据为数组并排序
    const dailySummary = Object.values(dailyData).sort((a, b) => a.date.localeCompare(b.date));
    
    // 创建最终返回的统计摘要
    const summary = {
      userId: userId || null,
      period,
      startDate,
      endDate,
      totalRecords: aggregatedData.totalRecords,
      totalCalories: aggregatedData.totalCalories,
      averageDailyCalories: Math.round(aggregatedData.totalCalories / days),
      nutritionTotal: {
        protein: Math.round(aggregatedData.totalProtein * 10) / 10,
        fat: Math.round(aggregatedData.totalFat * 10) / 10,
        carbohydrate: Math.round(aggregatedData.totalCarbohydrate * 10) / 10
      },
      nutritionAverage: {
        protein: Math.round((aggregatedData.totalProtein / days) * 10) / 10,
        fat: Math.round((aggregatedData.totalFat / days) * 10) / 10,
        carbohydrate: Math.round((aggregatedData.totalCarbohydrate / days) * 10) / 10
      },
      mealTypeSummary,
      dailySummary
    };
    
    logger.info(`【饮食记录统计】统计完成，共 ${summary.totalRecords} 条记录, ${days} 天，总热量 ${summary.totalCalories} 卡路里`);
    return summary;
  } catch (error) {
    logger.error('【饮食记录统计】统计出错:', error);
    throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, '生成饮食记录统计失败');
  }
};


module.exports = {
  createDietRecord,
  queryDietRecords,
  getDietRecordById,
  updateDietRecordById,
  deleteDietRecordById,
  getDietRecordSummary,
}; 